"""
人员检测相关的数据模型定义
"""
from datetime import datetime
from typing import Optional, List, Dict, Any, Tuple
from pydantic import BaseModel, Field, field_validator, model_validator
from enum import Enum


class DetectionStatus(str, Enum):
    """检测状态枚举"""
    PENDING = "pending"
    PROCESSING = "processing"
    COMPLETED = "completed"
    FAILED = "failed"


class AlertLevel(str, Enum):
    """告警级别枚举"""
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"
    CRITICAL = "critical"


class PersonDetectionResult(BaseModel):
    """人员检测结果模型"""
    detection_id: str = Field(..., description="检测ID")
    camera_id: str = Field(..., description="摄像头ID")
    timestamp: datetime = Field(..., description="检测时间")
    frame_id: Optional[str] = Field(None, description="帧ID")
    persons: List[Dict[str, Any]] = Field([], description="检测到的人员列表")
    total_count: int = Field(0, description="人员总数")
    confidence_threshold: float = Field(0.5, description="置信度阈值")
    processing_time: Optional[float] = Field(None, description="处理时间(秒)")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "detection_id": "det_123456",
                "camera_id": "cam_001",
                "timestamp": "2024-01-01T12:00:00Z",
                "frame_id": "frame_789",
                "persons": [
                    {
                        "person_id": "person_001",
                        "bbox": [100, 150, 200, 400],
                        "confidence": 0.95,
                        "center": [150, 275]
                    }
                ],
                "total_count": 1,
                "confidence_threshold": 0.5,
                "processing_time": 0.15
            }
        }
    }


class PersonBoundingBox(BaseModel):
    """人员边界框模型"""
    x1: float = Field(..., description="左上角X坐标")
    y1: float = Field(..., description="左上角Y坐标")
    x2: float = Field(..., description="右下角X坐标")
    y2: float = Field(..., description="右下角Y坐标")
    confidence: float = Field(..., ge=0, le=1, description="置信度")
    
    @model_validator(mode='after')
    def validate_coordinates(self) -> 'PersonBoundingBox':
        if self.x2 <= self.x1:
            raise ValueError('x2 must be greater than x1')
        if self.y2 <= self.y1:
            raise ValueError('y2 must be greater than y1')
        return self
    
    def get_center(self) -> Tuple[float, float]:
        """获取中心点坐标"""
        return ((self.x1 + self.x2) / 2, (self.y1 + self.y2) / 2)
    
    def get_area(self) -> float:
        """获取边界框面积"""
        return (self.x2 - self.x1) * (self.y2 - self.y1)
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "x1": 100.0,
                "y1": 150.0,
                "x2": 200.0,
                "y2": 400.0,
                "confidence": 0.95
            }
        }
    }


class PersonInfo(BaseModel):
    """人员信息模型"""
    person_id: str = Field(..., description="人员ID")
    bbox: PersonBoundingBox = Field(..., description="边界框")
    center: Tuple[float, float] = Field(..., description="中心点坐标")
    tracking_id: Optional[str] = Field(None, description="跟踪ID")
    features: Optional[Dict[str, Any]] = Field(None, description="特征信息")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "person_id": "person_001",
                "bbox": {
                    "x1": 100.0,
                    "y1": 150.0,
                    "x2": 200.0,
                    "y2": 400.0,
                    "confidence": 0.95
                },
                "center": [150.0, 275.0],
                "tracking_id": "track_001",
                "features": {
                    "height": 250,
                    "width": 100
                }
            }
        }
    }


class DensityAnalysisResult(BaseModel):
    """密度分析结果模型"""
    analysis_id: str = Field(..., description="分析ID")
    camera_id: str = Field(..., description="摄像头ID")
    timestamp: datetime = Field(..., description="分析时间")
    total_persons: int = Field(..., description="总人数")
    density_score: float = Field(..., ge=0, description="密度评分")
    density_level: str = Field(..., description="密度等级")
    regions: List[Dict[str, Any]] = Field([], description="区域分析结果")
    hotspots: List[Dict[str, Any]] = Field([], description="热点区域")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "analysis_id": "analysis_123",
                "camera_id": "cam_001",
                "timestamp": "2024-01-01T12:00:00Z",
                "total_persons": 25,
                "density_score": 0.75,
                "density_level": "high",
                "regions": [
                    {
                        "region_id": "region_1",
                        "person_count": 15,
                        "area": 1000,
                        "density": 0.015
                    }
                ],
                "hotspots": [
                    {
                        "center": [320, 240],
                        "radius": 50,
                        "person_count": 8
                    }
                ]
            }
        }
    }


class CrowdAlert(BaseModel):
    """人群告警模型"""
    alert_id: str = Field(..., description="告警ID")
    camera_id: str = Field(..., description="摄像头ID")
    alert_type: str = Field(..., description="告警类型")
    alert_level: AlertLevel = Field(..., description="告警级别")
    timestamp: datetime = Field(..., description="告警时间")
    person_count: int = Field(..., description="人员数量")
    density_score: float = Field(..., description="密度评分")
    location: Optional[Dict[str, Any]] = Field(None, description="位置信息")
    description: str = Field(..., description="告警描述")
    resolved: bool = Field(False, description="是否已解决")
    resolved_at: Optional[datetime] = Field(None, description="解决时间")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "alert_id": "alert_123",
                "camera_id": "cam_001",
                "alert_type": "crowd_gathering",
                "alert_level": "high",
                "timestamp": "2024-01-01T12:00:00Z",
                "person_count": 50,
                "density_score": 0.9,
                "location": {
                    "center": [320, 240],
                    "radius": 100
                },
                "description": "检测到异常人群聚集",
                "resolved": False
            }
        }
    }


class DetectionConfig(BaseModel):
    """检测配置模型"""
    confidence_threshold: float = Field(0.5, ge=0, le=1, description="置信度阈值")
    nms_threshold: float = Field(0.4, ge=0, le=1, description="NMS阈值")
    max_detections: int = Field(100, ge=1, description="最大检测数量")
    input_size: Tuple[int, int] = Field((640, 640), description="输入尺寸")
    enable_tracking: bool = Field(True, description="是否启用跟踪")
    tracking_max_age: int = Field(30, description="跟踪最大年龄")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "confidence_threshold": 0.6,
                "nms_threshold": 0.4,
                "max_detections": 50,
                "input_size": [640, 640],
                "enable_tracking": True,
                "tracking_max_age": 30
            }
        }
    }


class DensityConfig(BaseModel):
    """密度分析配置模型"""
    grid_size: Tuple[int, int] = Field((10, 10), description="网格大小")
    density_threshold: float = Field(0.1, description="密度阈值")
    alert_threshold: float = Field(0.8, description="告警阈值")
    smoothing_factor: float = Field(0.3, description="平滑因子")
    hotspot_radius: int = Field(50, description="热点半径")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "grid_size": [10, 10],
                "density_threshold": 0.1,
                "alert_threshold": 0.8,
                "smoothing_factor": 0.3,
                "hotspot_radius": 50
            }
        }
    }


class DetectionTask(BaseModel):
    """检测任务模型"""
    task_id: str = Field(..., description="任务ID")
    camera_id: str = Field(..., description="摄像头ID")
    task_type: str = Field(..., description="任务类型")
    status: DetectionStatus = Field(DetectionStatus.PENDING, description="任务状态")
    config: DetectionConfig = Field(..., description="检测配置")
    created_at: datetime = Field(..., description="创建时间")
    started_at: Optional[datetime] = Field(None, description="开始时间")
    completed_at: Optional[datetime] = Field(None, description="完成时间")
    progress: float = Field(0.0, ge=0, le=100, description="进度百分比")
    error_message: Optional[str] = Field(None, description="错误信息")
    results: Optional[List[PersonDetectionResult]] = Field(None, description="检测结果")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "task_id": "task_123",
                "camera_id": "cam_001",
                "task_type": "person_detection",
                "status": "processing",
                "config": {
                    "confidence_threshold": 0.6,
                    "nms_threshold": 0.4,
                    "max_detections": 50
                },
                "created_at": "2024-01-01T12:00:00Z",
                "progress": 45.5
            }
        }
    }


class ModelInfo(BaseModel):
    """模型信息模型"""
    model_id: str = Field(..., description="模型ID")
    model_name: str = Field(..., description="模型名称")
    model_type: str = Field(..., description="模型类型")
    version: str = Field(..., description="版本")
    framework: str = Field(..., description="框架")
    input_shape: Tuple[int, int, int] = Field(..., description="输入形状")
    classes: List[str] = Field(..., description="类别列表")
    accuracy: Optional[float] = Field(None, description="准确率")
    inference_time: Optional[float] = Field(None, description="推理时间(ms)")
    model_size: Optional[int] = Field(None, description="模型大小(MB)")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "model_id": "yolov8n_person",
                "model_name": "YOLOv8 Nano Person Detection",
                "model_type": "object_detection",
                "version": "8.0.0",
                "framework": "ultralytics",
                "input_shape": [3, 640, 640],
                "classes": ["person"],
                "accuracy": 0.89,
                "inference_time": 15.5,
                "model_size": 6
            }
        }
    }


class PerformanceMetrics(BaseModel):
    """性能指标模型"""
    metric_id: str = Field(..., description="指标ID")
    model_id: str = Field(..., description="模型ID")
    timestamp: datetime = Field(..., description="时间戳")
    fps: float = Field(..., description="帧率")
    inference_time: float = Field(..., description="推理时间(ms)")
    preprocessing_time: float = Field(..., description="预处理时间(ms)")
    postprocessing_time: float = Field(..., description="后处理时间(ms)")
    memory_usage: float = Field(..., description="内存使用(MB)")
    gpu_utilization: Optional[float] = Field(None, description="GPU利用率(%)")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "metric_id": "metrics_123",
                "model_id": "yolov8n_person",
                "timestamp": "2024-01-01T12:00:00Z",
                "fps": 30.5,
                "inference_time": 15.2,
                "preprocessing_time": 2.1,
                "postprocessing_time": 3.8,
                "memory_usage": 512.0,
                "gpu_utilization": 75.5
            }
        }
    }


class HeatmapData(BaseModel):
    """热力图数据模型"""
    heatmap_id: str = Field(..., description="热力图ID")
    camera_id: str = Field(..., description="摄像头ID")
    timestamp: datetime = Field(..., description="时间戳")
    width: int = Field(..., description="宽度")
    height: int = Field(..., description="高度")
    grid_size: Tuple[int, int] = Field(..., description="网格大小")
    data: List[List[float]] = Field(..., description="热力图数据")
    max_value: float = Field(..., description="最大值")
    min_value: float = Field(..., description="最小值")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "heatmap_id": "heatmap_123",
                "camera_id": "cam_001",
                "timestamp": "2024-01-01T12:00:00Z",
                "width": 640,
                "height": 480,
                "grid_size": [32, 24],
                "data": [[0.1, 0.2], [0.3, 0.4]],
                "max_value": 1.0,
                "min_value": 0.0
            }
        }
    }


class EvacuationRoute(BaseModel):
    """疏散路径模型"""
    route_id: str = Field(..., description="路径ID")
    start_point: Tuple[float, float] = Field(..., description="起始点")
    end_point: Tuple[float, float] = Field(..., description="终点")
    waypoints: List[Tuple[float, float]] = Field([], description="路径点")
    distance: float = Field(..., description="路径长度")
    estimated_time: float = Field(..., description="预计时间(秒)")
    capacity: int = Field(..., description="容量")
    current_load: int = Field(0, description="当前负载")
    blocked: bool = Field(False, description="是否阻塞")
    
    model_config = {
        "json_schema_extra": {
            "example": {
                "route_id": "route_001",
                "start_point": [100, 200],
                "end_point": [500, 600],
                "waypoints": [[200, 300], [300, 400], [400, 500]],
                "distance": 500.0,
                "estimated_time": 120.0,
                "capacity": 100,
                "current_load": 25,
                "blocked": False
            }
        }
    }